#include "stdafx.h"
#include "XFontImpl.h"

#include "UIDefaultValue.h"
#include "SkinObjMgr.h"

#include "IntSkinImpl.h"

IMPLEMENT_SKIN_CLASS(CXFontImpl);



CXFontImpl::CXFontImpl()
{
    m_hFont = NULL;
    m_hOldFont = NULL;
    m_lFontSize = XDEFAULT_TEXT_FONT_SIZE;

    m_dwFontFlags = 0;
    m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Bold, XDEFAULT_TEXT_BOLD);
    m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Italic, XDEFAULT_TEXT_ITALIC);
    m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Underline, XDEFAULT_TEXT_UNDERLINE);
    m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_StrikeOut, XDEFAULT_TEXT_STRIKEOUT);

    XSkinObjMgr* pSkinObjMgr = XSkinObjMgr::instance();
    if(pSkinObjMgr == NULL)
        m_strFontName = XDEFAULT_TEXT_FIRST_FONTNAME;
    else
        m_strFontName = pSkinObjMgr->GetDefaultFontName();
}

CXFontImpl::~CXFontImpl()
{
    ;
}

//////////////////////////////////////////////////////////////////////////
// IXDrawContextObj
void CXFontImpl::SetupCanvas(XCANVAS canvas)
{
    XASSERT_ERROR(m_hOldFont == NULL, _T("Font Selected in Canvas Already!"));
    if(m_hOldFont != NULL)
        return;

    m_hOldFont = ::SelectObject((HDC)canvas, GetFont());
    DWORD dwLastError = ::GetLastError();
#ifdef _DEBUG
    if(m_hOldFont == NULL)
    {
        int a = 0;
        LOGFONT LogFont = {0};
        int nResult = ::GetObject(m_hFont, sizeof(LogFont), &LogFont);
        HWND hWnd = ::WindowFromDC((HDC)canvas);
        m_hOldFont = ::SelectObject((HDC)canvas, GetFont());
    }
#endif	// _DEBUG
    XASSERT_ERROR(m_hOldFont != NULL, _T("Font Selected in Canvas Failed!"));
}

void CXFontImpl::RestoreCanvas(XCANVAS canvas)
{
    XASSERT_ERROR(m_hOldFont != NULL, _T("Font not Selected in Canvas!"));
    ::SelectObject((HDC)canvas, m_hOldFont);
    m_hOldFont = NULL;
}

XHANDLE CXFontImpl::get_DrawObj()
{
    return (XHANDLE)GetFont();
}

//////////////////////////////////////////////////////////////////////////
// IXFont
void CXFontImpl::put_FontSize(IN LONG lFontSize)
{
    if(m_lFontSize != lFontSize)
    {
        m_lFontSize = lFontSize;
        UpdateFont();
    }
}

void CXFontImpl::put_Bold(IN BOOL bBold)
{
    BOOL bOldBold = IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Bold);
    if((bOldBold && !bBold) || (!bOldBold && bBold))
    {
        m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Bold, bBold);
        UpdateFont();
    }
}

void CXFontImpl::put_Italic(IN BOOL bItalic)
{
    BOOL bOldItalic = IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Italic);
    if((bOldItalic && !bItalic) || (!bOldItalic && bItalic))
    {
        m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Italic, bItalic);
        UpdateFont();
    }
}

void CXFontImpl::put_Underline(IN BOOL bUnderline)
{
    BOOL bOldUnderline = IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Underline);
    if((bOldUnderline && !bUnderline) || (!bOldUnderline && bUnderline))
    {
        m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_Underline, bUnderline);
        UpdateFont();
    }
}

void CXFontImpl::put_StrikeOut(IN BOOL bStrikeOut)
{
    BOOL bOldStrikeOut = IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_StrikeOut);
    if((bOldStrikeOut && !bStrikeOut) || (!bOldStrikeOut && bStrikeOut))
    {
        m_dwFontFlags = IntSkinImpl::ModifyFlags(m_dwFontFlags, XFont_StrikeOut, bStrikeOut);
        UpdateFont();
    }
}

void CXFontImpl::put_FontName(IN LPCTSTR szFontName)
{
    if(m_strFontName.CompareNoncase(szFontName) != 0)
    {
        m_strFontName = szFontName;
        UpdateFont();
    }
}

LONG CXFontImpl::get_FontSize()
{
    return m_lFontSize;
}

BOOL CXFontImpl::get_Bold()
{
    return IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Bold);
}

BOOL CXFontImpl::get_Italic()
{
    return IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Italic);
}

BOOL CXFontImpl::get_Underline()
{
    return IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Underline);
}

BOOL CXFontImpl::get_StrikeOut()
{
    return IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_StrikeOut);
}

void CXFontImpl::get_FontName(BSTR* pbstrFontName)
{
    ::SysReAllocString(pbstrFontName, m_strFontName);
}

//////////////////////////////////////////////////////////////////////////
void CXFontImpl::OnFinalRelease()
{
    superclass::OnFinalRelease();
    ReleaseFont();
}

//////////////////////////////////////////////////////////////////////////
void CXFontImpl::UpdateFont()
{
    ReleaseFont();
}

HFONT CXFontImpl::GetFont()
{
    if(m_hFont != NULL)
    {
        return m_hFont;
    }
    XSkinObjMgr* pSkinObjMgr = XSkinObjMgr::instance();
    m_hFont = (pSkinObjMgr == NULL) ? NULL
        : pSkinObjMgr->GetFont(m_lFontSize,
        IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Bold),
        IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Italic),
        IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_Underline),
        IntSkinImpl::CheckFlags(m_dwFontFlags, XFont_StrikeOut),
        m_strFontName);
    XASSERT_ERROR(m_hFont != NULL, _T("CreateFont Failed"));

    return m_hFont;
}

void CXFontImpl::ReleaseFont()
{
    if(m_hFont != NULL)
    {
        XSkinObjMgr* pSkinObjMgr = XSkinObjMgr::instance();
        XASSERT_ERROR(pSkinObjMgr != NULL, _T("XSkinObjMgr::instance() Failed."));
        if(pSkinObjMgr != NULL)
        {
            pSkinObjMgr->ReleaseFont(m_hFont);
        }
        m_hFont = NULL;
    }
}
